package com.zsk.shop.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.zsk.shop.api.order.OrderStatus;
import com.zsk.shop.api.pay.ali.api.FundTransUniTransfer;
import com.zsk.shop.api.pay.ali.bean.AliTransactionType;
import com.zsk.shop.api.pay.common.bean.PayOrder;
import com.zsk.shop.api.pay.common.bean.RefundOrder;
import com.zsk.shop.api.pay.common.enums.PayTypeEnum;
import com.zsk.shop.api.pay.common.util.PayUtil;
import com.zsk.shop.api.pay.wx.bean.WxTransactionType;
import com.zsk.shop.common.base.BaseResponse;
import com.zsk.shop.common.base.BizException;
import com.zsk.shop.common.constant.Constant;
import com.zsk.shop.common.constant.RedisKeys;
import com.zsk.shop.common.utils.*;
import com.zsk.shop.config.interceptor.ErrorHandler;
import com.zsk.shop.config.pay.WeixinPayConfig;
import com.zsk.shop.entity.*;
import com.zsk.shop.enums.*;
import com.zsk.shop.mapper.ShopOrderMapper;
import com.zsk.shop.model.params.*;
import com.zsk.shop.model.results.ConfirmOrderResult;
import com.zsk.shop.model.results.ShopOrderInfoResult;
import com.zsk.shop.model.results.ShopOrderListResult;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author yuwenbo
 * @since 2020-04-19
 */
@Service
@DS("miniShop")
@Slf4j
public class ShopOrderService extends ServiceImpl<ShopOrderMapper, ShopOrder> {

    private static final Logger logger = LoggerFactory.getLogger(ShopOrderService.class);

    @Resource
    private WeixinPayConfig weixinPayConfig;
    @Resource
    private ShopUserService userService;
    @Resource
    private DingTalkRootUtil dingTalkRootUtil;
    @Resource
    private Environment environment;
    @Resource
    private FundTransUniTransfer fundTransUniTransfer;
    @Resource
    private ShopGoodsSkuService goodsSkuService;
    @Resource
    private ShopGoodsService goodsService;
    @Resource
    private ShopOrderPointsService shopOrderPointsService;
    @Resource
    private DeliveryAddressStatusService deliveryAddressStatusService;
    @Resource
    private UserAccountService userAccountService;
    @Resource
    private DataDictionaryService dataDictionaryService;

    public BaseResponse<ShopOrderListResult> getOrderList(GetOrderParam param) {
        String userNo = HttpContext.getUserNo();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        List<ShopOrderListResult> results = this.getBaseMapper().getOrderList(userNo, param.getOrderStatus(), PageWithSqlUtil.getIndex(param.getPage(), param.getLimit()), PageWithSqlUtil.getSize(param.getPage(), param.getLimit()));
        for (ShopOrderListResult obj : results) {
            if (ToolUtil.isNotEmpty(obj.getSnapshot())) {
                OrderGoodsSnapshotParam snapshotParam = new Gson().fromJson(obj.getSnapshot(), OrderGoodsSnapshotParam.class);
                if (ToolUtil.isNotEmpty(snapshotParam)) {
                    if (ToolUtil.isNotEmpty(snapshotParam.getImg())) {
                        obj.setSkuImg(snapshotParam.getImg());
                    }
                    obj.setReturnPoints(snapshotParam.getReturnPoints());
                    obj.setGoodsName(snapshotParam.getGoodsName());
                    obj.setGoodsImg(snapshotParam.getGoodsImg());
                }
            }
            obj.setSnapshot(null);
            Integer cancelTime = Integer.parseInt(RedisUtil.get(RedisKeys.dictionaryKey(EnumDataDictionaryKey.ORDER_CANCEL_TIME.getKey())).toString());
            obj.setCancelTime(format.format(DateUtils.addMinuteOfDate(obj.getCreateTime(), cancelTime)));
        }
        return BaseResponse.success("列表数据", results, this.getBaseMapper().getOrderCount(userNo, param.getOrderStatus()));
    }

    public BaseResponse<ShopOrderInfoResult> getOrderInfo(String orderNo) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        ShopOrder order = this.queryOne(orderNo);
        if (ToolUtil.isNotEmpty(order)) {
            ShopOrderInfoResult result = EntityConvertUtils.convertAToB(order, ShopOrderInfoResult.class);
            if (ToolUtil.isNotEmpty(order.getSnapshot())) {
                OrderGoodsSnapshotParam snapshotParam = new Gson().fromJson(order.getSnapshot(), OrderGoodsSnapshotParam.class);
                if (ToolUtil.isNotEmpty(snapshotParam)) {
                    if (ToolUtil.isNotEmpty(snapshotParam.getImg())) {
                        result.setSkuImg(snapshotParam.getImg());
                    } else {
                        result.setSkuImg(snapshotParam.getGoodsImg().split(",")[0]);
                    }
                    result.setGoodsName(snapshotParam.getGoodsName());
                    result.setGoodsImg(snapshotParam.getGoodsImg());
                }
            }
            if (order.getOrderStatus().equals(EnumOrderStatus.DELIVERY_STATUS.getCode())) {
                DeliveryAddressStatus number = deliveryAddressStatusService.queryOne(result.getOrderNo());
                if (ToolUtil.isEmpty(number)) {
                    result.setExpName("无");
                    result.setDeliveryStatus("无");
                    result.setDeliverTime(new Date());
                } else {
                    try {
                        Map<String, String> map = OrderStatus.getLogisticsName(number.getNumber());
                        result.setExpName(map.get("expName"));
                        result.setDeliveryStatus(map.get("deliveryStatus"));
                        result.setDeliverTime(number.getCreateTime());
                        result.setExpNumber(number.getNumber());
                    } catch (Exception e) {
                        result.setExpNumber(number.getNumber());
                        result.setExpName("无");
                        result.setDeliveryStatus("无");
                        result.setDeliverTime(new Date());
                    }
                }
            }
            Integer cancelTime = Integer.parseInt(RedisUtil.get(RedisKeys.dictionaryKey(EnumDataDictionaryKey.ORDER_CANCEL_TIME.getKey())).toString());
            result.setCancelTime(format.format(DateUtils.addMinuteOfDate(result.getCreateTime(), cancelTime)));
            return BaseResponse.success(result);
        }
        return BaseResponse.error("订单不存在");
    }

    public BaseResponse updateOrderEndStatus(String orderNo, String status) {
        LambdaUpdateWrapper<ShopOrder> objectQueryWrapper = new LambdaUpdateWrapper<>();
        objectQueryWrapper.eq(ShopOrder::getOrderNo, orderNo);
        objectQueryWrapper.set(ShopOrder::getOrderStatus, status);
        objectQueryWrapper.set(ShopOrder::getDeliveryTime, new Date());
        update(objectQueryWrapper);
        if (EnumOrderStatus.CANCEL_ORDER.getCode().equals(status)
                || EnumOrderStatus.ORDER_CANCEL_TIME.getCode().equals(status)
                || EnumOrderStatus.CANCEL_ORDER_REFUND.getCode().equals(status)) {
            //还原库存
            ShopOrder order = queryOne(orderNo);
            OrderGoodsSnapshotParam snapshotParam = new Gson().fromJson(order.getSnapshot(), OrderGoodsSnapshotParam.class);
            if (ToolUtil.isNotEmpty(snapshotParam)) {
                goodsSkuService.addGoodsSkuStock(snapshotParam.getBizNo(), order.getGoodsNumber());
            }
        }
        return BaseResponse.success();
    }

    public BaseResponse<ConfirmOrderResult> getOrderInfo(ConfirmOrderParams param) {
        BigDecimal price = new BigDecimal(0);
        ShopGoodsSku skuInfo = goodsSkuService.getGoodsSkuInfo(param.getBizNo());
        ConfirmOrderResult result = new ConfirmOrderResult();
        if (ToolUtil.isNotEmpty(skuInfo)) {
            BigDecimal postage = BigDecimal.ZERO;
            result.setGoodsNumber(param.getGoodsNumber());
            result.setGoodsOrderType(param.getGoodsOrderType());
            result.setImg(skuInfo.getImg());
            if (param.getGoodsOrderType().equals(1)) {
                result.setPrice(skuInfo.getPrice());
                if (ToolUtil.isNotEmpty(skuInfo.getSpecialPrice()) && skuInfo.getSpecialPrice().compareTo(price) == 1) {
                    result.setSpecialPrice(skuInfo.getSpecialPrice());
                    result.setAmount(skuInfo.getSpecialPrice().multiply(new BigDecimal(param.getGoodsNumber())));
                } else {
                    result.setSpecialPrice(price);
                    result.setAmount(skuInfo.getPrice().multiply(new BigDecimal(param.getGoodsNumber())));
                }
            } else if (param.getGoodsOrderType().equals(2)) {
                postage = new BigDecimal(RedisUtil.get(RedisKeys.dictionaryKey(EnumDataDictionaryKey.POSTAGE.getKey())).toString());
                result.setPrice(price);
                result.setPostage(postage);
                result.setAmount(BigDecimal.ZERO);
            } else if (param.getGoodsOrderType().equals(3)) {
                result.setPrice(skuInfo.getPrice());
                result.setVipPrice(skuInfo.getVipPrice());
                result.setAmount(skuInfo.getVipPrice().multiply(new BigDecimal(param.getGoodsNumber())));
            } else if (param.getGoodsOrderType().equals(4)) {
                result.setReturnPoints(skuInfo.getReturnPoints());
                result.setPrice(skuInfo.getPrice());
                if (ToolUtil.isNotEmpty(skuInfo.getSpecialPrice()) && skuInfo.getSpecialPrice().compareTo(price) == 1) {
                    result.setSpecialPrice(skuInfo.getSpecialPrice());
                    result.setAmount(skuInfo.getSpecialPrice().multiply(new BigDecimal(param.getGoodsNumber())));
                } else {
                    result.setSpecialPrice(price);
                    result.setAmount(skuInfo.getPrice().multiply(new BigDecimal(param.getGoodsNumber())));
                }
            } else if (param.getGoodsOrderType().equals(5)) {
                result.setReturnPoints(skuInfo.getReturnPoints());
                result.setPrice(skuInfo.getPrice());
                result.setAgainPrice(skuInfo.getAgainPrice());
                result.setSpecialPrice(price);
                result.setAmount(skuInfo.getAgainPrice().multiply(new BigDecimal(param.getGoodsNumber())));
            }
            result.setTotalAmount(result.getAmount().add(postage));
            result.setGoodsName(skuInfo.getName());
        }
        return BaseResponse.success(result);
    }

    @Transactional(rollbackFor = {BizException.class, Exception.class})
    public synchronized BaseResponse add(ShopOrderParam param) throws Exception {
        String userNo = HttpContext.getUserNo();
        ShopUser appUser = userService.queryByUserNo(userNo);
        if (ToolUtil.isEmpty(appUser)) {
            return BaseResponse.error("用户不存在!");
        }
        if (ToolUtil.isEmpty(appUser.getParentUserNo())) {
            if (param.getGoodsOrderType().equals(4)) {
                String inviteCode = "";
                if (ToolUtil.isNotEmpty(param.getInviteCode())) {
                    inviteCode = param.getInviteCode();
                }
                String msg = userService.setParentUser2(inviteCode, null);
                if (ToolUtil.isNotEmpty(msg)) {
                    return BaseResponse.error(msg);
                } else {
                    userService.checkLv(inviteCode, null, true);
                }
            }
        }
        ShopGoodsSku result = goodsSkuService.getGoodsSkuInfo(param.getBizNo());
        if (ToolUtil.isEmpty(result)) {
            return BaseResponse.error("商品规格不存在!");
        }
        ShopGoods goods = goodsService.queryByGoodsNo(result.getGoodsNo());
        if (ToolUtil.isNotEmpty(goods)) {
            if (goods.getHavePreSaleTime()) {
                if (goods.getPreSaleTime().getTime() >= System.currentTimeMillis()) {
                    return BaseResponse.error("商品已售罄!");
                }
            }
            if (!goods.getStatus()) {
                return BaseResponse.error("该商品已下架!");
            }
        } else {
            return BaseResponse.error("该商品不存在!");
        }
        if (result.getStock() <= 0) {
            return BaseResponse.error("该商品已售完!");
        }
        if ((result.getStock() - param.getGoodsNumber()) < 0) {
            return BaseResponse.error("商品库存不足!");
        }
        if (param.getGoodsOrderType().equals(3)) {
            if (getUserOrderNumber(userNo) <= 0) {
                return BaseResponse.error("您未获得会员购资格\n购买指定商品 即可获得会员购资格");
            }
        }
        if (param.getGoodsOrderType().equals(2)) {
            if (param.getGoodsNumber() > 1) {
                return BaseResponse.error("该商品只能购买1件");
            }
            Integer zeroNum = Integer.parseInt(RedisUtil.get(RedisKeys.dictionaryKey(EnumDataDictionaryKey.ZERO.getKey())).toString());
            if (getUserOrderNumber(userNo) < zeroNum) {
                return BaseResponse.error("您未获得0元购资格\n购买指定商品满" + zeroNum + "次 即可获得0元购资格");
            }
            if (this.baseMapper.getUserPuyNumber(userNo, 2) >= 1) {
                return BaseResponse.error("这个月已使用过0元购服务啦 下个月再来吧!");
            }
        }
        if (param.getGoodsOrderType().equals(5)) {
            if (ToolUtil.isEmpty(param.getOrderPointsNo())) {
                return BaseResponse.error("请选择抵扣红包!");
            }
            ShopOrderPoints orderPointsInfo = shopOrderPointsService.getShopOrderPointsInfo(param.getOrderPointsNo());
            if (ToolUtil.isEmpty(orderPointsInfo)) {
                return BaseResponse.error("该红包已使用!");
            }
            if (param.getGoodsNumber() > 1) {
                return BaseResponse.error("该商品只能购买1件");
            }
        }
        log.info("请求参数:{}", new Gson().toJson(param));
        ShopOrder orderParam = saveOrUpdate(result, param);
        if (ToolUtil.isEmpty(orderParam)) {
            return BaseResponse.error("订单异常，请重试...");
        }
        goodsSkuService.updateGoodsSku(param.getBizNo(), param.getGoodsNumber());
        return pay(orderParam.getOrderNo(), orderParam.getAmount(), param.getPayType(), appUser.getWxJsOpenId(), orderParam.getGoodsName());
    }

    /**
     * 获取用户购买特殊商品总数
     *
     * @param userNo
     * @return
     */
    public Integer getUserOrderNumber(String userNo) {
        LambdaQueryWrapper<ShopOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShopOrder::getUserNo, userNo);
        queryWrapper.and(x -> x.eq(ShopOrder::getOrderStatus, EnumOrderStatus.PAY_SUCCESS.getCode())
                .or().eq(ShopOrder::getOrderStatus, EnumOrderStatus.DELIVERY_STATUS.getCode())
                .or().eq(ShopOrder::getOrderStatus, EnumOrderStatus.COMPLETE.getCode()));
        queryWrapper.eq(ShopOrder::getGoodsOrderType, 4);
        return list(queryWrapper).stream().map(ShopOrder::getGoodsNumber).reduce(Integer::sum).orElse(0);
    }

    /**
     * 创建订单
     *
     * @param result
     * @param param
     * @return
     */
    public ShopOrder saveOrUpdate(ShopGoodsSku result, ShopOrderParam param) {
        ShopOrder orderParam = EntityConvertUtils.convertAToB(param, ShopOrder.class);
        BigDecimal price = new BigDecimal(0);
        try {
            String userNo = HttpContext.getUserNo();
            String goodsNo = result.getGoodsNo();
            orderParam.setGoodsNo(goodsNo);
            orderParam.setUserNo(userNo);
            orderParam.setOrderNo(StringUtils.getOrderNo());
            if (param.getGoodsOrderType().equals(1)) {
                if (ToolUtil.isNotEmpty(result.getSpecialPrice()) && result.getSpecialPrice().compareTo(price) == 1) {
                    orderParam.setAmount(result.getSpecialPrice().multiply(new BigDecimal(param.getGoodsNumber())));
                } else {
                    orderParam.setAmount(result.getPrice().multiply(new BigDecimal(param.getGoodsNumber())));
                }
            } else if (param.getGoodsOrderType().equals(2)) {
                BigDecimal postage = new BigDecimal(RedisUtil.get(RedisKeys.dictionaryKey(EnumDataDictionaryKey.POSTAGE.getKey())).toString());
                orderParam.setAmount(new BigDecimal(0.00).add(postage));
                orderParam.setPostage(postage);
            } else if (param.getGoodsOrderType().equals(3)) {
                orderParam.setAmount(result.getVipPrice().multiply(new BigDecimal(param.getGoodsNumber())));
            } else if (param.getGoodsOrderType().equals(4)) {
                orderParam.setReturnPoints(result.getReturnPoints());
                if (ToolUtil.isNotEmpty(result.getSpecialPrice()) && result.getSpecialPrice().compareTo(price) == 1) {
                    orderParam.setAmount(result.getSpecialPrice().multiply(new BigDecimal(param.getGoodsNumber())));
                } else {
                    orderParam.setAmount(result.getPrice().multiply(new BigDecimal(param.getGoodsNumber())));
                }
            } else if (param.getGoodsOrderType().equals(5)) {
                ShopOrderPoints orderPointsInfo = shopOrderPointsService.getShopOrderPointsInfo(param.getOrderPointsNo());
                orderParam.setDeductPoints(orderPointsInfo.getThawPoint());
                orderParam.setReturnPoints(result.getReturnPoints());
                orderParam.setAmount(result.getAgainPrice().multiply(new BigDecimal(param.getGoodsNumber())));
            }
            orderParam.setPayAmount(new BigDecimal(0.00));
            orderParam.setPayType(param.getPayType());
            orderParam.setOrderStatus(EnumOrderStatus.PAY_NOT.getCode());
            orderParam.setRefundStatus(EnumShopOrderRefundStatus.REFUND_NOT.getCode());
            orderParam.setCreateTime(new Date());
            OrderGoodsSnapshotParam goodsSnapshotParam = EntityConvertUtils.convertAToB(result, OrderGoodsSnapshotParam.class);
            ShopGoods goods = goodsService.queryByGoodsNo(goodsNo);
            if (ToolUtil.isNotEmpty(goods)) {
                goodsSnapshotParam.setGoodsName(goods.getGoodsName());
                goodsSnapshotParam.setGoodsImg(goods.getGoodsImgs());
                goodsSnapshotParam.setGoodsCategoryNo(goods.getGoodsCategoryNo());
                goodsSnapshotParam.setGoodsOrderType(param.getGoodsOrderType());
                if(goods.getGoodsType().equals(EnumGoodsType.AGAIN.getType())){
                    goodsSnapshotParam.setVipLevel(goods.getAgainVipLevel());
                }else {
                    goodsSnapshotParam.setVipLevel(goods.getVipLevel());
                }
                orderParam.setGoodsName(goodsSnapshotParam.getGoodsName() + " " + goodsSnapshotParam.getName());
            } else {
                orderParam.setGoodsName("商品");
            }
            String snapshot = JSON.toJSONString(goodsSnapshotParam);
            orderParam.setSnapshot(snapshot);
            logger.info("保存订单信息,{}", JSONObject.toJSONString(orderParam));
            orderParam.setParentUserNo("");
            if (goods.getGoodsType() >= 0) {
                String parentUserNo = userService.queryParentUserNo(userNo, goods.getVipLevel());
                orderParam.setParentUserNo(parentUserNo);
            }
            this.saveOrUpdate(orderParam);

            return orderParam;
        } catch (Exception e) {
            log.error("修改失败", e);
            return null;
        }
    }

    /**
     * 删除订单
     *
     * @param id
     * @return
     */
    public BaseResponse deleteOrder(Long id) {
        LambdaUpdateWrapper<ShopOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(ShopOrder::getIsDeleted, true);
        updateWrapper.eq(ShopOrder::getId, id);
        this.update(updateWrapper);
        return BaseResponse.success();
    }

    /**
     * 生成支付串
     *
     * @param tradeNo
     * @param price
     * @param payType
     * @param openId
     * @param body
     * @return
     * @throws Exception
     */
    public synchronized BaseResponse pay(String tradeNo, BigDecimal price, Integer payType, String openId, String body) throws Exception {
        if (!Constant.isProd()) {
            price = new BigDecimal("0.01");
        }
        PayOrder payOrder = new PayOrder(body, body, price, tradeNo);
        if (payType.equals(PayTypeEnum.ALIPAY.getCode())) {
            Map<String, Object> data = new HashMap<>(20);
//            //App支付宝支付
            payOrder.setTransactionType(AliTransactionType.APP);
            data.put("orderStr", fundTransUniTransfer.createOrder(payOrder));
            data.put("tradeNo", tradeNo);
            return new BaseResponse(BaseResponse.SUCCESS, "App支付宝支付", data, tradeNo);
        } else if (payType.equals(PayTypeEnum.WECHAT.getCode())) {
            payOrder.setTransactionType(WxTransactionType.APP);
            //App微信支付
            Map<String, String> map = weixinPayConfig.wxPay(tradeNo, price, body);
            if (ToolUtil.isEmpty(map.get("prepayid"))) {
                return BaseResponse.error("订单创建失败");
            }
            return new BaseResponse(BaseResponse.SUCCESS, "App微信支付", map, tradeNo);
        } else if (payType.equals(PayTypeEnum.MINI.getCode())) {
            payOrder.setTransactionType(WxTransactionType.MINI);
            payOrder.setOpenid(openId);
            //小程序支付
            Map orderInfo = weixinPayConfig.getPayServiceMINI().orderInfo(payOrder);
            return new BaseResponse(BaseResponse.SUCCESS, "小程序支付", orderInfo, tradeNo);
        } else if (payType.equals(PayTypeEnum.JSAPI.getCode())) {
            payOrder.setTransactionType(WxTransactionType.JSAPI);
            payOrder.setOpenid(openId);
            Map map = weixinPayConfig.getPayServiceMINI().orderInfo(payOrder);
            logger.info("JSAPI支付返回参数==" + new Gson().toJson(map));
//            if (ToolUtil.isEmpty(map.get("package"))) {
//                return BaseResponse.error("订单创建失败");
//            }
            return new BaseResponse(BaseResponse.SUCCESS, "JSAPI微信支付", map, tradeNo);
        } else if (payType.equals(PayTypeEnum.H5.getCode())) {
            payOrder.setTransactionType(WxTransactionType.MWEB);
            payOrder.setWapUrl("https://zhishangkeapp.com");
            payOrder.setWapName("商品购买");
            Map map = weixinPayConfig.getPayServiceH5().h5OrderInfo(payOrder);
            logger.info("H5支付返回参数==" + new Gson().toJson(map));
            return new BaseResponse(BaseResponse.SUCCESS, "H5微信支付", map, tradeNo);
        }
        return BaseResponse.error("支付错误");
    }

    /**
     * 订单中未支付->>>支付
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = {BizException.class, Exception.class})
    public synchronized BaseResponse orderPay(Long id, Integer payType) throws Exception {
        String userNo = HttpContext.getUserNo();
        ShopOrder order = this.getById(id);
        if (ToolUtil.isEmpty(order)) {
            return BaseResponse.error("订单不存在!");
        }
        ShopUser appUser = userService.queryByUserNo(order.getUserNo());
        if (ToolUtil.isEmpty(appUser)) {
            return BaseResponse.error("用户不存在!");
        }
        if (order.getGoodsOrderType().equals(3)) {
            if (getUserOrderNumber(userNo) <= 0) {
                return BaseResponse.error("您未获得会员购资格\n购买指定商品 即可获得会员购资格");
            }
        }
        if (order.getGoodsOrderType().equals(2)) {
            if (order.getGoodsNumber() > 1) {
                return BaseResponse.error("该商品只能购买1件");
            }
            Integer zeroNum = Integer.parseInt(RedisUtil.get(RedisKeys.dictionaryKey(EnumDataDictionaryKey.ZERO.getKey())).toString());
            if (getUserOrderNumber(userNo) < zeroNum) {
                return BaseResponse.error("您未获得0元购资格\n购买指定商品满" + zeroNum + "次 即可获得0元购资格");
            }
            if (this.baseMapper.getUserPuyNumber(userNo, 2) >= 1) {
                return BaseResponse.error("这个月已使用过0元购服务啦 下个月再来吧!");
            }
        }
        if (order.getGoodsOrderType().equals(5)) {
            ShopOrderPoints orderPointsInfo = shopOrderPointsService.getShopOrderPointsInfo(order.getOrderPointsNo());
            if (ToolUtil.isEmpty(orderPointsInfo)) {
                return BaseResponse.error("该红包已使用!");
            }
        }
        String orderNo = StringUtils.getOrderNo();
        RedisUtil.setForTimeMIN("shop:" + orderNo, order.getOrderNo(), 20);
        if (!Constant.isProd()) {
            order.setAmount(new BigDecimal("0.01"));
        }
        PayOrder payOrder = new PayOrder("订单支付", "订单支付", order.getAmount(), orderNo);
        updateOrderPayType(id, payType);
        if (payType.equals(PayTypeEnum.ALIPAY.getCode())) {
            Map<String, Object> data = new HashMap<>(20);
            payOrder.setTransactionType(AliTransactionType.APP);
            data.put("orderStr", fundTransUniTransfer.createOrder(payOrder));
            data.put("tradeNo", orderNo);
            return new BaseResponse(BaseResponse.SUCCESS, "App支付宝支付", data, orderNo);
        } else if (payType.equals(PayTypeEnum.WECHAT.getCode())) {
            payOrder.setTransactionType(WxTransactionType.APP);
            Map<String, String> map = weixinPayConfig.wxPay(orderNo, order.getAmount(), "智商客商品够买");
            if (ToolUtil.isEmpty(map.get("prepayid"))) {
                return BaseResponse.error("订单创建失败");
            }
            return new BaseResponse(BaseResponse.SUCCESS, "App微信支付", map, orderNo);
        } else if (payType.equals(PayTypeEnum.JSAPI.getCode())) {
            payOrder.setTransactionType(WxTransactionType.JSAPI);
            payOrder.setOpenid(appUser.getWxJsOpenId());
            Map map = weixinPayConfig.getPayServiceMINI().orderInfo(payOrder);
            logger.info("JSAPI支付返回参数==" + new Gson().toJson(map));
//            if (ToolUtil.isEmpty(map.get("prepayid"))) {
//                return BaseResponse.error("订单创建失败");
//            }
            return new BaseResponse(BaseResponse.SUCCESS, "JSAPI微信支付", map, orderNo);
        } else if (payType.equals(PayTypeEnum.H5.getCode())) {
            payOrder.setTransactionType(WxTransactionType.MWEB);
            payOrder.setWapUrl("https://zhishangkeapp.com");
            payOrder.setWapName("商品购买");
            Map map = weixinPayConfig.getPayServiceH5().h5OrderInfo(payOrder);
            return new BaseResponse(BaseResponse.SUCCESS, "H5支付", map.get("mweb_url"), order.getOrderNo());
        }
        return new BaseResponse(BaseResponse.SUCCESS, "支付", order, order.getOrderNo());
    }

    public void aliPcPay(HttpServletRequest request, HttpServletResponse response, Long id, Integer payType) throws Exception {
        String userNo = HttpContext.getUserNo();
        ShopOrder order = this.getById(id);
        if (ToolUtil.isEmpty(order)) {
            throw new BizException("订单不存在!");
        }
        ShopUser appUser = userService.queryByUserNo(order.getUserNo());
        if (ToolUtil.isEmpty(appUser)) {
            throw new BizException("用户不存在!");
        }
        if (order.getGoodsOrderType().equals(3)) {
            if (getUserOrderNumber(userNo) <= 0) {
                throw new BizException("您未获得会员购资格\n购买指定商品 即可获得会员购资格");
            }
        }
        if (order.getGoodsOrderType().equals(2)) {
            if (order.getGoodsNumber() > 1) {
                throw new BizException("该商品只能购买1件");
            }
            Integer zeroNum = Integer.parseInt(RedisUtil.get(RedisKeys.dictionaryKey(EnumDataDictionaryKey.ZERO.getKey())).toString());
            if (getUserOrderNumber(userNo) < zeroNum) {
                throw new BizException("您未获得0元购资格\\n购买指定商品满\" + zeroNum + \"次 即可获得0元购资格");
            }
            if (this.baseMapper.getUserPuyNumber(userNo, 2) >= 1) {
                throw new BizException("这个月已使用过0元购服务啦 下个月再来吧!");
            }
        }
        if (order.getGoodsOrderType().equals(5)) {
            ShopOrderPoints orderPointsInfo = shopOrderPointsService.getShopOrderPointsInfo(order.getOrderPointsNo());
            if (ToolUtil.isEmpty(orderPointsInfo)) {
                throw new BizException("该红包已使用!");
            }
        }
        String orderNo = StringUtils.getOrderNo();
        RedisUtil.setForTimeMIN("shop:" + orderNo, order.getOrderNo(), 20);
        PayOrder payOrder = new PayOrder("订单支付", "订单支付", order.getAmount(), orderNo);
        updateOrderPayType(id, payType);
        fundTransUniTransfer.createPcOrder(request, response, payOrder);
    }

    public void createPcOrder(HttpServletRequest request, HttpServletResponse response, ShopOrderParam param) throws Exception {
        String userNo = HttpContext.getUserNo();
        ShopUser appUser = userService.queryByUserNo(userNo);
        if (ToolUtil.isEmpty(appUser)) {
            throw new BizException("用户不存在!");
        }
        if (ToolUtil.isEmpty(appUser.getParentUserNo())) {
            if (param.getGoodsOrderType().equals(4)) {
                String inviteCode = "";
                if (ToolUtil.isNotEmpty(param.getInviteCode())) {
                    inviteCode = param.getInviteCode();
                }
                String msg = userService.setParentUser2(inviteCode, null);
                if (ToolUtil.isNotEmpty(msg)) {
                    throw new BizException(msg);
                } else {
                    userService.checkLv(inviteCode, null, true);
                }
            }
        }
        ShopGoodsSku result = goodsSkuService.getGoodsSkuInfo(param.getBizNo());
        if (ToolUtil.isEmpty(result)) {
            throw new BizException("商品规格不存在!");
        }
        ShopGoods goods = goodsService.queryByGoodsNo(result.getGoodsNo());
        if (ToolUtil.isNotEmpty(goods)) {
            if (goods.getHavePreSaleTime()) {
                if (goods.getPreSaleTime().getTime() >= System.currentTimeMillis()) {
                    throw new BizException("商品已售罄!");
                }
            }
            if (!goods.getStatus()) {
                throw new BizException("该商品已下架!");
            }
        } else {
            throw new BizException("该商品不存在!");
        }
        if (result.getStock() <= 0) {
            throw new BizException("该商品已售完!");
        }
        if ((result.getStock() - param.getGoodsNumber()) < 0) {
            throw new BizException("商品库存不足!");
        }
        if (param.getGoodsOrderType().equals(3)) {
            if (getUserOrderNumber(userNo) <= 0) {
                throw new BizException("您未获得会员购资格\n购买指定商品 即可获得会员购资格");
            }
        }
        if (param.getGoodsOrderType().equals(2)) {
            if (param.getGoodsNumber() > 1) {
                throw new BizException("该商品只能购买1件");
            }
            Integer zeroNum = Integer.parseInt(RedisUtil.get(RedisKeys.dictionaryKey(EnumDataDictionaryKey.ZERO.getKey())).toString());
            if (getUserOrderNumber(userNo) < zeroNum) {
                throw new BizException("您未获得0元购资格\n购买指定商品满" + zeroNum + "次 即可获得0元购资格");
            }
            if (this.baseMapper.getUserPuyNumber(userNo, 2) >= 1) {
                throw new BizException("这个月已使用过0元购服务啦 下个月再来吧!");
            }
        }
        if (param.getGoodsOrderType().equals(5)) {
            if (ToolUtil.isEmpty(param.getOrderPointsNo())) {
                throw new BizException("请选择抵扣红包!");
            }
            ShopOrderPoints orderPointsInfo = shopOrderPointsService.getShopOrderPointsInfo(param.getOrderPointsNo());
            if (ToolUtil.isEmpty(orderPointsInfo)) {
                throw new BizException("该红包已使用!");
            }
            if (param.getGoodsNumber() > 1) {
                throw new BizException("该商品只能购买1件!");
            }
        }
        log.info("请求参数:{}", new Gson().toJson(param));
        ShopOrder orderParam = saveOrUpdate(result, param);
        if (ToolUtil.isEmpty(orderParam)) {
            throw new BizException("订单异常，请重试...");
        }
        goodsSkuService.updateGoodsSku(param.getBizNo(), param.getGoodsNumber());
        PayOrder payOrder = new PayOrder(orderParam.getGoodsName(), orderParam.getGoodsName(), orderParam.getAmount(), orderParam.getOrderNo());
        fundTransUniTransfer.createPcOrder(request, response, payOrder);
    }

    public void refund(ShopOrder order, String description, Boolean envIsProd) throws BizException {
        String msg = "";
        String msgBiz = "";
        try {
            RefundOrder refundOrder = new RefundOrder();
            refundOrder.setOutTradeNo(order.getOrderNo());
            if (ToolUtil.isNotEmpty(order) && ToolUtil.isNotEmpty(order.getTransactionId())) {
                refundOrder.setTradeNo(order.getTransactionId());
            }
            refundOrder.setRefundNo(RedisUtil.getServiceKeyHaveDateByType(ServiceKeyTypeEnum.R.getValue()));
            refundOrder.setRefundAmount(new BigDecimal("0.01"));
            refundOrder.setTotalAmount(new BigDecimal("0.01"));
            envIsProd = ToolUtil.isEmpty(envIsProd) ? Constant.isProd() : envIsProd;
            if (envIsProd) {
                refundOrder.setRefundAmount(order.getPayAmount());
                refundOrder.setTotalAmount(order.getAmount());
            }
            refundOrder.setDescription(description);
            //小程序
            if (order.getPayType().equals(PayTypeEnum.MINI.getCode())) {
                Map<String, Object> params = weixinPayConfig.getPayServiceMINI().refund(refundOrder);
                msg = PayUtil.wxHandld(params);
            }
        } catch (Exception e) {
            msgBiz = "退款失败:" + order.getOrderNo() + ",描述:" + description + "," + e.getMessage();
            logger.error(msgBiz);
            dingTalkRootUtil.send("退款失败" + "异常信息" + e.getMessage()
                    + "\n" + ErrorHandler.getExceptionText(e) + ",订单集合: + 订单:" + order.getOrderNo()
                    + ",原因：回调异常  操作：支付", "", false);
            msg = "退款失败";

        }
        if (ToolUtil.isNotEmpty(msg)) {
            throw new BizException(msgBiz);
//            throw new BizException("退款失败: " + msg);
        }
        //还原库存
    }

    private void refundWithoutStock(ShopOrder order, String description, Boolean envIsProd) {
        String msg = "";
        String msgBiz = "";
        try {
            RefundOrder refundOrder = new RefundOrder();
            refundOrder.setOutTradeNo(order.getOrderNo());
            if (ToolUtil.isNotEmpty(order) && ToolUtil.isNotEmpty(order.getTransactionId())) {
                refundOrder.setTradeNo(order.getTransactionId());
            }
            refundOrder.setRefundNo(RedisUtil.getServiceKeyHaveDateByType(ServiceKeyTypeEnum.R.getValue()));
            refundOrder.setRefundAmount(new BigDecimal("0.01"));
            refundOrder.setTotalAmount(new BigDecimal("0.01"));
            envIsProd = ToolUtil.isEmpty(envIsProd) ? Constant.isProd() : envIsProd;
            if (envIsProd) {
                refundOrder.setRefundAmount(order.getPayAmount());
                refundOrder.setTotalAmount(order.getAmount());
            }
            refundOrder.setDescription(description);
            //小程序
            if (order.getPayType().equals(PayTypeEnum.MINI.getCode())) {
                Map<String, Object> params = weixinPayConfig.getPayServiceMINI().refund(refundOrder);
                msg = PayUtil.wxHandld(params);
            }
        } catch (Exception e) {
            msgBiz = "退款失败:" + order.getOrderNo() + ",描述:" + description + "," + e.getMessage();
            logger.error(msgBiz);
            dingTalkRootUtil.send("退款失败" + "异常信息" + e.getMessage()
                    + "\n" + ErrorHandler.getExceptionText(e) + ",订单集合: + 订单:" + order.getOrderNo()
                    + ",原因：回调异常  操作：支付", "", false);
            msg = "退款失败";
        }
        if (ToolUtil.isNotEmpty(msg)) {
            throw new BizException(msgBiz);
//            throw new BizException("退款失败: " + msg);
        }
    }

    public void updateOrderStatus(String orderNo, String status, String transactionId, BigDecimal payAmount) {
        LambdaUpdateWrapper<ShopOrder> objectQueryWrapper = new LambdaUpdateWrapper<>();
        objectQueryWrapper.eq(ShopOrder::getOrderNo, orderNo);
        objectQueryWrapper.set(ShopOrder::getOrderStatus, status);
        objectQueryWrapper.set(ShopOrder::getPayAmount, payAmount);
        objectQueryWrapper.set(ShopOrder::getTransactionId, transactionId);
        objectQueryWrapper.set(ShopOrder::getPayTime, new Date());
        update(objectQueryWrapper);
    }

    public void updateOrderPayType(Long id, Integer payType) {
        LambdaUpdateWrapper<ShopOrder> objectQueryWrapper = new LambdaUpdateWrapper<>();
        objectQueryWrapper.eq(ShopOrder::getId, id);
        objectQueryWrapper.set(ShopOrder::getPayType, payType);
        update(objectQueryWrapper);
    }

    public ShopOrder queryOne(String orderNo) {
        QueryWrapper<ShopOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ShopOrder::getOrderNo, orderNo);
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    public ShopOrder queryOnePayNot(String orderNo) {
        QueryWrapper<ShopOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ShopOrder::getOrderNo, orderNo);
        queryWrapper.lambda().eq(ShopOrder::getOrderStatus, EnumOrderStatus.PAY_NOT.getCode());
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    /**
     * 统计该商品No的商品销量
     *
     * @param goodsNo
     * @return
     */
    public Integer countByGoodsNo(String goodsNo) {
        LambdaQueryWrapper<ShopOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShopOrder::getGoodsNo, goodsNo);
        return list(queryWrapper).size();
    }

    public List<ShopOrder> listGoodsByUserNos(List<String> userNos, Date startTime, Date endTime) {
        userNos = userNos.stream().distinct().collect(Collectors.toList());
        if (ToolUtil.isEmpty(userNos)) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<ShopOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ShopOrder::getUserNo, userNos);
        queryWrapper.ne(ShopOrder::getRefundStatus, EnumShopOrderRefundStatus.REFUND_SUCCESS.getCode());
        queryWrapper.isNotNull(ShopOrder::getPayTime);
        queryWrapper.ge(ShopOrder::getPayTime, startTime);
        queryWrapper.le(ShopOrder::getPayTime, endTime);
        return list(queryWrapper);
    }

    public List<ShopOrder> listAmountGoodsBuyUserNos(List<String> userNos, Date startTime, Date endTime) {
        userNos = userNos.stream().distinct().collect(Collectors.toList());
        LambdaQueryWrapper<ShopOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ShopOrder::getUserNo, userNos);
        queryWrapper.ne(ShopOrder::getGoodsOrderType, 2);
        queryWrapper.ne(ShopOrder::getRefundStatus, EnumShopOrderRefundStatus.REFUND_SUCCESS.getCode());
        queryWrapper.isNotNull(ShopOrder::getPayTime);
        if (ToolUtil.isNotEmpty(startTime)) {
            queryWrapper.ge(ShopOrder::getPayTime, startTime);
        }
        queryWrapper.le(ShopOrder::getPayTime, endTime);
        return list(queryWrapper);
    }

    public void addParentFirst(ShopOrder order) {
        //0元购不给直推
        if (order.getGoodsOrderType().equals(2)) {
            return;
        }
        String userNo = order.getUserNo();
        ShopUser user = userService.queryByUserNo(userNo);
        if (ToolUtil.isEmpty(user) || ToolUtil.isEmpty(user.getParentUserNo())) {
            return;
        }
        ShopUser parentUser = userService.queryByUserNo(user.getParentUserNo());
        if (ToolUtil.isNotEmpty(parentUser)) {
            if (parentUser.getVipLevel() < 1) {
                return;
            }
        } else {
            return;
        }
        OrderGoodsSnapshotParam snapshotParam = new Gson().fromJson(order.getSnapshot(), OrderGoodsSnapshotParam.class);
        Integer goodsVipLevel = ToolUtil.isNotEmpty(snapshotParam.getVipLevel()) ? snapshotParam.getVipLevel() : 0;
        if (parentUser.getVipLevel().equals(EnumVipLevel.ONE.getCode())) {
            //如果用户vip等级为普通会员，商品层级太高不分钱
            if (goodsVipLevel > EnumVipLevel.ONE.getCode()) {
                return;
            }
        }
        String parentUserNo = parentUser.getUserNo();
        String money;
//        if (Constant.isProd()) {
//            money = order.getPayAmount().divide(BigDecimal.TEN).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
//        } else {
//            money = order.getAmount().divide(BigDecimal.TEN).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
//        }
        //todo 修改成实际金额
        money = order.getPayAmount().divide(BigDecimal.TEN).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
        MoneyAccountInsertParams params = MoneyAccountInsertParams.builder()
                .userNo(parentUserNo).changeType(EnumUserAccountChangeType.PARENT_FIRST.getCode()).money(money)
                .orderNo(order.getOrderNo()).build();
        userAccountService.moneyAccountInsert(params);
        //二推
        if (order.getGoodsOrderType().equals(4)) {
            if (ToolUtil.isNotEmpty(parentUser.getParentUserNo())) {
                ShopUser parentUser1 = userService.queryByUserNo(parentUser.getParentUserNo());
                if (ToolUtil.isNotEmpty(parentUser1) && parentUser1.getVipLevel() > 0) {
                    //判断等级 是否平级奖
                    if (!parentUser1.getLv().equals(parentUser.getLv())) {
                        return;
                    }
                    if (parentUser1.getVipLevel().equals(EnumVipLevel.ONE.getCode())) {
                        //如果用户vip等级为普通会员，商品层级太高不分钱
                        if (goodsVipLevel > EnumVipLevel.ONE.getCode()) {
                            return;
                        }
                    }
                    String parentUserNo1 = parentUser1.getUserNo();
                    BigDecimal ratio = EnumRatioWithLv.getRecommendRatioByLv(parentUser1.getLv());
                    String money1 = new BigDecimal(money).multiply(ratio).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
                    if (money1.equals("0.00")) {
                        return;
                    }
                    MoneyAccountInsertParams params1 = MoneyAccountInsertParams.builder()
                            .userNo(parentUserNo1).changeType(EnumUserAccountChangeType.PARENT_SECOND.getCode()).money(money1)
                            .orderNo(order.getOrderNo()).build();
                    userAccountService.moneyAccountInsert(params1);
                }
            }
        }
        return;
    }

    public void handleDeliveryOvertimeStatus() {
        Date time = new Date();
        LambdaQueryWrapper<ShopOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShopOrder::getOrderStatus, EnumOrderStatus.DELIVERY_STATUS.getCode());
        DataDictionary dictionary = dataDictionaryService.getValueByKey(Constant.OVER_DELIVERY_DAY);
        Integer overDay = ToolUtil.isEmpty(dictionary) ? 14 : Integer.parseInt(dictionary.getValue());
        queryWrapper.and(x -> x.isNotNull(ShopOrder::getDeliveryTime).ge(ShopOrder::getDeliveryTime, DateUtils.addDayOfDate(time, overDay)));
        List<ShopOrder> wmOrderList = list(queryWrapper);
        if (ToolUtil.isEmpty(wmOrderList)) {
            return;
        }
        for (ShopOrder wmOrder : wmOrderList) {
            wmOrder.setOrderStatus(EnumOrderStatus.COMPLETE.getCode());
            wmOrder.setDoneTime(time);
        }
        saveOrUpdateBatch(wmOrderList);
        return;
    }

    public List<ShopOrder> listAmountByUserNos(List<String> userNoLists, Date startTime, Date endTime) {
        LambdaQueryWrapper<ShopOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ShopOrder::getUserNo, userNoLists);
        //计算业绩剔除0元购
        queryWrapper.ne(ShopOrder::getGoodsOrderType, 2);
        queryWrapper.ge(ShopOrder::getPayTime, startTime);
        queryWrapper.le(ShopOrder::getPayTime, endTime);
        queryWrapper.and(x -> x.eq(ShopOrder::getOrderStatus, EnumOrderStatus.PAY_SUCCESS.getCode())
                .or().eq(ShopOrder::getOrderStatus, EnumOrderStatus.DELIVERY_STATUS.getCode())
                .or().eq(ShopOrder::getOrderStatus, EnumOrderStatus.COMPLETE.getCode()));
        queryWrapper.and(y -> y.eq(ShopOrder::getRefundStatus, EnumShopOrderRefundStatus.REFUND_NOT.getCode())
                .or().eq(ShopOrder::getRefundStatus, EnumShopOrderRefundStatus.REFUND_REJECT.getCode()));
        return list(queryWrapper);
    }

    public List<ShopOrder> teamAmountByUserNo(String userNo, Date startDay, Date endDay) {
        //        userNo = "US2022032522070024";
        ShopUser shopUser = userService.queryByUserNo(userNo);
        List<String> userNosList = userService.entityConvertIds2Nos(shopUser.getSubUserId());
        userNosList.add(userNo);
        List<ShopOrder> shopOrderListAll = new ArrayList<>();
        if (ToolUtil.isNotEmpty(userNosList)) {
            LambdaQueryWrapper<ShopOrder> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.isNotNull(ShopOrder::getParentUserNo);
            queryWrapper.ne(ShopOrder::getParentUserNo, "");
            if (!ToolUtil.isAllEmpty(startDay, endDay)) {
                queryWrapper.ge(ShopOrder::getPayTime, startDay);
                queryWrapper.le(ShopOrder::getPayTime, endDay);
            }
            queryWrapper.and(x -> x.in(ShopOrder::getParentUserNo, userNosList).or(y -> y.eq(ShopOrder::getUserNo, userNo)));
            queryWrapper.ne(ShopOrder::getGoodsOrderType, 2);
            queryWrapper.and(x -> x.eq(ShopOrder::getOrderStatus, EnumOrderStatus.PAY_SUCCESS.getCode())
                    .or().eq(ShopOrder::getOrderStatus, EnumOrderStatus.DELIVERY_STATUS.getCode())
                    .or().eq(ShopOrder::getOrderStatus, EnumOrderStatus.COMPLETE.getCode()));
            shopOrderListAll = list(queryWrapper);
        }
        return shopOrderListAll;
    }

    /**
     * 计算当前用户下有多上礼包商品属于他
     *
     * @param userNo
     * @param startTime
     * @param endTime
     * @return
     */
    public List<ShopOrder> countSpecialGoodsByUserNo(String userNo, Date startTime, Date endTime) {
        LambdaQueryWrapper<ShopOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.apply("user_no != parent_user_no");
        queryWrapper.eq(ShopOrder::getParentUserNo, userNo);
        queryWrapper.eq(ShopOrder::getGoodsOrderType, 4);
        queryWrapper.ne(ShopOrder::getRefundStatus, EnumShopOrderRefundStatus.REFUND_SUCCESS.getCode());
        queryWrapper.isNotNull(ShopOrder::getPayTime);
        queryWrapper.ge(ShopOrder::getPayTime, startTime);
        queryWrapper.le(ShopOrder::getPayTime, endTime);
        return list(queryWrapper);
    }

}
